// components/baseForm/baseForm.js
const app = getApp();
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多 slot 支持
  },
  properties: {
    title: {
      type: String,
      value: ''
    },
    zh: {
      type: String,
      value: '页面接口描述'
    },
    remark: {
      type: String,
      value: ''
    },//需要特殊备注的信息
    //表单配置
    schema: {
      type: Array,
      value: []
    },
    result:null,
    formData:{
      type: Object,
      value: {}
    },
    weburl: {
      type: String,
      value: ''
    }, // 文档地址
    apiName: {
      type: String,
      value: ''
    }, // api名称
    useScroll: {
      type: Boolean,
      value: true
    },
    useCustomBar: {
      type: Boolean,
      value: true
    }
  },
  data: {
    canvasHeight:400,
    showResult:false,
    systemInfo:{},
    richNodes:[],
    textareaValue:'',
    originResult: '',
    showMenu:false,
    labels:{},
    statusBarHeight: 0,
    paddingTopHeight: 0,
  },
  observers: {
    'result.**': function (profile) {
      if(profile===null||Object.keys(profile).length>0||(typeof profile === 'boolean')) {
        // this.drawImage(profile)
        // this.drawJson(profile)
        
        this.setData({
          showResult: true,
          richNodes:this.jsonToHtml(profile,0),
          originResult: profile,
          // textareaValue:JSON.stringify(profile)
          textareaValue: this.jsonToCustom(profile,0)
        })
      }
    },
  },
  attached() {
  },
  ready(){
    this.setData({
      systemInfo:wx.getDeviceInfo(),
      statusBarHeight: app.globalData.systemInfoData.statusBarHeight,
      paddingTopHeight: app.globalData.systemInfoData.statusBarHeight + app.globalData.menuInfo.height
    })
  },
  methods: {
    previewResult(){
      wx.canvasToTempFilePath({
        canvasId: 'jsonCanvas',
        success: (res) => {
          wx.previewImage({
            current:res.tempFilePath,
            urls: [res.tempFilePath]
          })
        }
      }, this);
    },
    inputNum(e){
      const extraIndex = e.currentTarget.dataset.extra;
      const inputValue = e.detail.value;
      let extraParam = this.data.schema[extraIndex]
      if(extraParam.numRang!=null&&parseInt(inputValue)>extraParam.numRang[1]){
        extraParam.value = extraParam.numRang[1]
      }else if(extraParam.numRang!=null&&parseInt(inputValue)<=extraParam.numRang[0]){
        extraParam.value = extraParam.numRang[0]
      }else{
        extraParam.value = inputValue
      }
      console.log("SSS:",extraParam)
      this.triggerEvent('schemaDataChange',{
        index:extraIndex,
        data:extraParam
      })
    },
    formDataFilter(formData) {
      const newFormData = {}
      this.data.schema.forEach(item => {
        if(item.type === 'number') {
          if(!isNaN(+formData[item.prop]) && formData[item.prop] !== '') {
            newFormData[item.prop] = +formData[item.prop]
          }
        } else {
          newFormData[item.prop] = formData[item.prop]
        }
      })
      console.log('newFormData', newFormData);
      return newFormData
    },
    pickerChange(e) {
      let index = e.target.dataset.index
      let item = this.data.schema[index]
      this.setData({
        [`formData.${item.prop}`]:item.valueOptions[e.detail.value]
      })
      let data = {
        prop: item.prop,
        formData: this.formDataFilter(this.data.formData)
      }
      this.triggerEvent('formDataChange',data)
    },
    dataChange(e) {
      let prop = e.target.dataset.prop
      this.setData({
        [`formData.${prop}`]:e.detail.value
      })
      let data = {
        prop: prop,
        formData: this.formDataFilter(this.data.formData)
      }
      this.triggerEvent('formDataChange',data)
    },
    showBottomMenu() {
      this.setData({
        showMenu:true
      })
    },
    multiSelectChange(e){
      let prop = e.target.dataset.prop
      this.setData({
        [`labels.${prop}`]:e.detail.label,
        [`formData.${prop}`]:e.detail.select
      })
      let data = {
        prop: prop,
        formData: this.formDataFilter(this.data.formData)
      }
      this.triggerEvent('formDataChange',data)
    },
    drawImage(res) {
      console.log(res)
      const ctx = wx.createCanvasContext('jsonCanvas', this);
      const jsonStr = JSON.stringify(res, null, 2);
      const lines = jsonStr.split('\n');
      
      const keyColor = "#d14"; // 重点颜色
      const valueColor = "#fff"; // 普通颜色
      const fontSize = 16;
      const lineHeight = 22;
      const padding = 20
      const canvasWidth = wx.getSystemInfoSync().windowWidth
      let canvasHeight = 400
      ctx.setFillStyle("#000")
      ctx.fillRect(0, 0, canvasWidth, canvasHeight);
      let y = padding
      // 递归绘制
      const drawObj = (obj, indent = 0) => {
        for (let key in obj) {
          // key
          ctx.setFontSize(fontSize);
          ctx.setFillStyle(keyColor);
          ctx.fillText(key + ': ', 10 + indent * 20, y);
  
          // value
          ctx.setFontSize(fontSize);
          ctx.setFillStyle(valueColor);
          let value = obj[key];
          let valueStr = '';
            if (Array.isArray(value)) {
              y += lineHeight;
              drawObj(value,indent + 1)
            } else if(typeof value === 'object' && value !== null){
              y += lineHeight;
              drawObj(value, indent + 1);
            } else{
              valueStr = JSON.stringify(value);
              y = drawValueWrap(ctx, valueStr, 10 + indent * 20 + ctx.measureText(key + ': ').width, y, canvasWidth, valueColor, fontSize, lineHeight);
            }
          
          y += lineHeight;
          // 检查高度
          if (y > canvasHeight-lineHeight) {
            canvasHeight += 400 // 增加高度
            this.setData({
              canvasHeight:canvasHeight
            })
            ctx.setFillStyle("#000")
            ctx.fillRect(0, canvasHeight-400, canvasWidth, 400);
          }
        }
      };
  
      // 自动换行绘制 value
      function drawValueWrap(ctx, text, x, y, maxWidth, color, fontSize, lineHeight) {
        ctx.setFontSize(fontSize);
        ctx.setFillStyle(color);
        let start = 0;
        let textWidth = 0;
        for (let i = 1; i <= text.length; i++) {
          let subStr = text.substring(start, i);
          let width = ctx.measureText(subStr).width;
          if (x + width > maxWidth - 30) {
            ctx.fillText(text.substring(start, i - 1), x, y);
            y += lineHeight;
            start = i - 1;
            x = 10;
          }
          textWidth = width;
        }
        ctx.fillText(text.substring(start), x, y);
        return y;
      }
      drawObj(res, 0);
      // ctx.setFillStyle("#000")
      // ctx.fillRect(0, 0, canvasWidth, this.data.canvasHeight);
      ctx.draw();
    },

    jsonToHtml(obj, indent) {
      const pad = n => '&nbsp;'.repeat(n * 4);//
      if (Array.isArray(obj)) {
        let arr = '[\n';//
        obj.forEach((item, i) => {
          arr += pad(indent + 1) + this.jsonToHtml(item, indent + 1);
          if (i < obj.length - 1) arr += ',<br>';//<br>
        });
        arr += '<br>' + pad(indent) + ']';//<br>
        return arr;
      } else if (typeof obj === 'object' && obj !== null) {
        let str = '{<br>';//<br>
        const keys = Object.keys(obj);
        keys.forEach((key, i) => {
          str += pad(indent + 1) +
            `<span style="color:#c00;">"${key}"</span>: ` +
            this.jsonToHtml(obj[key], indent + 1);
          if (i < keys.length - 1) str += ',<br>';//<br>
        });
        str += '<br>' + pad(indent) + '}';//<br>
        return str;
      } else if (typeof obj === 'string') {
        return `<span style="color:#080;word-wrap: break-word;">"${obj}"</span>`;
      } else if (typeof obj === 'number') {
        return `<span style="color:#00c;word-wrap: break-word;">${obj}</span>`;
      } else if (typeof obj === 'boolean') {
        return `<span style="color:#a50;">${obj}</span>`;
      } else if (obj === null) {
        return `<span style="color:#999;">null</span>`;
      } else if (typeof obj === 'function') {
        const name = obj.name ? `: ${obj.name}` : '';
        return `<span style="color:#b0b;">[Function${name}]</span>`;
      }
      return '';
    },
    jsonToCustom(obj, indent) {
      const pad = n => '\t'.repeat(n * 4);//&nbsp;
      if (Array.isArray(obj)) {
        let arr = '[\n';//<br>
        obj.forEach((item, i) => {
          arr += pad(indent + 1) + this.jsonToCustom(item, indent + 1);
          if (i < obj.length - 1) arr += ',\n';//<br>
        });
        arr += '\n' + pad(indent) + ']';//<br>
        return arr;
      } else if (typeof obj === 'object' && obj !== null) {
        let str = '{\n';//<br>
        const keys = Object.keys(obj);
        keys.forEach((key, i) => {
          str += pad(indent + 1) +
            `"${key}":` + this.jsonToCustom(obj[key], indent + 1);
          if (i < keys.length - 1) str += ',\n';//<br>
        });
        str += '\n' + pad(indent) + '}';//<br>
        return str;
      } else if (typeof obj === 'string') {
        return `"${obj}"`;
      } else if (typeof obj === 'number') {
        return `${obj}`;
      } else if (typeof obj === 'boolean') {
        return `${obj}`;
      } else if (obj === null) {
        return "null";
      } else if (typeof obj === 'function') {
        const name = obj.name ? `: ${obj.name}` : '';
        return `[Function${name}]`;
      }
      return '';
    },
    drawJson(res) {
      const ctx = wx.createCanvasContext('jsonCanvas', this);
      const lineHeight = 24;
      const fontSize = 16;
      const padding = 20
      let x = padding;
      let y = padding+20;
      const canvasWidth = wx.getSystemInfoSync().windowWidth
      let canvasHeight = 400
      ctx.setFillStyle("#000")
      ctx.fillRect(0, 0, canvasWidth, canvasHeight);
      // 绘制边框
      // ctx.setStrokeStyle('#666');
      // ctx.strokeRect(0, 0, canvasWidth, canvasHeight);
  
      // 格式化并绘制 JSON
      const drawLine = (text, color, indent = 0,append,addX) => {
        ctx.setFontSize(fontSize);
        ctx.setFillStyle(color);
        let words = text.split('');
        let line = '';
        let maxWidth = canvasWidth - padding * 2 - indent * 20-20;
        for (let i = 0; i < words.length; i++) {
          let testLine = line + words[i];
          let metrics = ctx.measureText(testLine);
          if (metrics.width > maxWidth-(append?addX:0) && line !== '') {
            ctx.fillText(line, append&&append==true?x + indent * 10+addX:x + indent * 10, append&&append==true?y-lineHeight:y);
            y += lineHeight;
            line = words[i];
          } else {
            line = testLine;
          }
        }
        if (line) {
          if(append&&append==true){
            y = y-lineHeight
          }
          ctx.fillText(line, append&&append==true?x + indent * 10+addX:x + indent * 10, y);
          // ctx.fillText(line, x + indent * 20, y);
          y += lineHeight;
          // 检查高度
          if (y > canvasHeight-lineHeight) {
            canvasHeight += 400 // 增加高度
            this.setData({
              canvasHeight:canvasHeight
            })
            ctx.setFillStyle("#000")
            ctx.fillRect(0, canvasHeight-400, canvasWidth, 400);
          }
        }
      };
  
      const renderJson = (obj, indent = 0,append,addX) => {
        console.log("addX:",append,addX)
        if (Array.isArray(obj)) {
          drawLine('[', '#fff', indent+1);
          obj.forEach((item, idx) => {
            renderJson(item, indent + 1);
          });
          drawLine(']', '#fff', indent+1);
        } else if (typeof obj === 'object' && obj !== null) {
          drawLine('{', '#fff', indent);
          const keys = Object.keys(obj);
          keys.forEach((key, idx) => {
              drawLine(`"${key}": `, '#FF6600', indent + 1);
              console.log("这里输出key，是否追加：",key,obj[key])
              renderJson(obj[key], indent + 1,!Array.isArray(obj[key]),ctx.measureText(`"${key}": `).width+5);
          });
          drawLine('}', '#fff', indent);
        } else if (typeof obj === 'string') {
          drawLine(`"${obj}"`+",", '#fff', indent,append,addX);
        } else if (typeof obj === 'number') {
          drawLine(obj.toString()+",", '#0099FF', indent,append,addX);
        } else if (typeof obj === 'boolean') {
          drawLine(obj ? 'true' : 'false'+",", '#FF0000', indent,append,addX);
        } else if (obj === null) {
          drawLine('null'+",", '#888888', indent,append,addX);
        }
      };
  
      renderJson(res, 0);
  
      ctx.draw();
    },
    openDocFunc() {
      wx.navigateTo({
        url: '/page/webview/webview?src='+this.data.weburl,
      })
    },
    // 导出输出结果
    exportTxtFileFunc() {
      const deviceInfo = wx.getDeviceInfo();
      if(deviceInfo.platform === 'devtools' || deviceInfo.platform === 'android' || deviceInfo.platform === 'ios') {
        getApp().api.createApiTxt({
          name: this.data.apiName,
          result: JSON.stringify(this.data.originResult)
        }).then(res=>{
          console.log(res.data)
        }).catch(e =>{
          console.error(e)
        })
      }
    }
  }
})